using System;
using System.IO;

namespace Seaskyer.WebApp.Utility.BigUpload
{
	/// <summary>
	/// 
	/// </summary>
	public class UploadFile
	{
		#region Properties

		/// <summary>
		/// Gets the length (in bytes) of the uploaded file.
		/// </summary>
		public long ContentLength
		{
			get { return this.filelength; }
		}

		/// <summary>
		/// Gets the MIME content type of the uploaded file.
		/// </summary>
		public string ContentType
		{
			get { return this.contenttype; }
		}

		/// <summary>
		/// Gets the file name(including path) of the uploaded file as it was on the client machine.
		/// </summary>
		public string FileName
		{
			get { return this.filename; }
		}

		/// <summary>
		/// Gets the path of where the uploaded file was located on the server machine.
		/// </summary>
		public string FilePath
		{
			get { return this.filepath; }
		}

		#endregion

		#region Fields

		private string contenttype;
		private long filelength;
		private string filename;
		private string filepath;

		#endregion

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		public UploadFile(string name)
		{
			if ((name == null) || (name == string.Empty))
			{
				throw new ArgumentNullException("Name", "Name can not be null!");
			}

			string content = String.Empty;	

			this.filename = string.Empty;
			this.filepath = string.Empty;
			this.contenttype = string.Empty;
			this.filelength = 0;
			
			if (IsContentHeader(name))
			{
				content = name;
			}
			else if (IsContentHeader(Utils.GetContext().Request[name]))
			{
				content = Utils.GetContext().Request[name];
			}

			if ((content == null) || (content == string.Empty))
			{
				return;
			}

			//Get file info from content.
			string[] contentArray = content.Split(';');

			this.contenttype = contentArray[0];
			this.contenttype = this.contenttype.Substring(14, (this.contenttype.Length - 14));
			this.filename = contentArray[1];
			this.filename = this.filename.Substring(10, (this.filename.Length - 11));
			this.filepath = contentArray[2];
			this.filepath = this.filepath.Substring(10, (this.filepath.Length - 11));

			string uploadFolder = Utils.GetUploadFolder();
			this.filepath = Path.Combine(uploadFolder, this.filepath);

			try
			{
				this.filelength = new FileInfo(this.filepath).Length;
			}
			catch (Exception exception)
			{
				string uploadGuid = Utils.GetContext().Request["Sunrise_Web_Upload_UploadGUID"];

				if (uploadGuid != null)
				{
					Utils.GetContext().Application.Remove(("_UploadGUID_" + uploadGuid));
				}

				throw exception;
			}
		}

		private bool IsContentHeader(string line)
		{
			if((line == null)
				||(line == String.Empty))
			{
				return false;
			}

			string[] contentArray = line.Split(';');

			if (((contentArray.Length == 3)
				&& contentArray[0].StartsWith("Content-Type:"))
				&& (contentArray[1].StartsWith("filename=\"")
				&& contentArray[2].StartsWith("filepath=\"")))
			{
				return true;
			}

			return false;
		}

		/// <summary>
		/// Save file to disk.
		/// </summary>
		/// <param name="filename"></param>
		public void SaveAs(string filename)
		{
			string uploadGuid = Utils.GetContext().Request["Sunrise_Web_Upload_UploadGUID"];

			try
			{
				UploadStatus uploadStatus;
				FileInfo fileInfo = new FileInfo(this.filepath);

				if (uploadGuid != null)
				{
					uploadStatus = new UploadStatus(uploadGuid);
					uploadStatus.State = UploadState.Moving;
					Utils.GetContext().Application[("_UploadGUID_" + uploadGuid)] = uploadStatus;
				}

				string directoryName = Path.GetDirectoryName(filename);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				else if (File.Exists(filename))
				{
					File.Delete(filename);
				}

				//Move temporary file to file that client uploaded. Simply change it's name.
				fileInfo.MoveTo(filename);
				if (uploadGuid == null)
				{
					return;
				}

				uploadStatus = new UploadStatus(uploadGuid);
				uploadStatus.State = UploadState.Completed;

				Utils.GetContext().Application[("_UploadGUID_" + uploadGuid)] = uploadStatus;
			}
			catch (Exception exception)
			{
				if (uploadGuid != null)
				{
					Utils.GetContext().Application.Remove(("_UploadGUID_" + uploadGuid));
				}

				throw exception;
			}
		}


	}

}